"""
聊天相关API路由
"""

from fastapi import APIRouter, HTTPException, Depends, Request
from fastapi.responses import StreamingResponse
from typing import List, Dict, Optional
import logging
import json
from pathlib import Path

from ...utils.ai_service import (
    AIService,
    ChatRequest,
    ChatResponse,
    ChatMessage,
    get_ai_service,
)
from ...utils.prompt import render_prompt
from ...utils.config import DATA_DIR
from ...utils.http import ExamResult
from ...utils.tools import json_loads

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/chat", tags=["聊天"])


async def load_exam_context(user_exam_id: str, request_headers: dict) -> Optional[Dict]:
    """
    加载考试上下文数据

    Args:
        user_exam_id: 用户考试ID
        request_headers: 请求头

    Returns:
        Dict: 考试上下文数据，如果加载失败返回None
    """
    if not user_exam_id:
        return None

    try:
        # 首先尝试从缓存文件读取
        result_file = DATA_DIR.joinpath(f"{user_exam_id}.json")
        if result_file.exists():
            logger.info(f"从缓存文件加载考试数据: {user_exam_id}")
            return json_loads(result_file.read_text(encoding="utf-8"))

        # 如果缓存不存在，从API获取
        logger.info(f"从API获取考试数据: {user_exam_id}")
        exam = ExamResult(user_exam_id, request_headers)
        exam_result = await exam.get_exam_result(user_exam_id)

        # 将原始数据转换为字典格式
        exam_data = exam_result.model_dump()
        logger.info(
            f"成功获取考试数据，题目数量: {len(exam_data.get('questions', []))}"
        )

        return exam_data

    except Exception as e:
        logger.error(f"加载考试上下文失败: {e}")
        return None


@router.post("/message", response_model=ChatResponse)
async def send_message(
    request: Request,
    chat_request: ChatRequest,
    ai_service: AIService = Depends(get_ai_service),
) -> ChatResponse:
    """
    发送聊天消息

    Args:
        request: HTTP请求对象
        chat_request: 聊天请求
        ai_service: AI服务实例

    Returns:
        ChatResponse: AI回复
    """
    try:
        logger.info(f"收到聊天请求，消息数量: {len(chat_request.messages)}")

        # 验证消息格式
        if not chat_request.messages:
            raise HTTPException(status_code=400, detail="消息列表不能为空")

        # 尝试获取考试ID并加载考试上下文
        user_exam_id = request.query_params.get("examId")
        exam_context = None

        if user_exam_id:
            logger.info(f"尝试加载考试上下文: {user_exam_id}")
            exam_context = await load_exam_context(user_exam_id, dict(request.headers))
            if exam_context:
                logger.info("成功加载考试上下文")
                # 将考试上下文合并到请求中
                chat_request.exam_context = exam_context
            else:
                logger.warning("加载考试上下文失败，使用默认上下文")

        # 调用AI服务
        response = await ai_service.chat(chat_request)

        logger.info(f"AI回复成功，内容长度: {len(response.content)}")
        return response

    except Exception as e:
        logger.error(f"聊天服务错误: {e}")
        raise HTTPException(status_code=500, detail=f"聊天服务错误: {str(e)}")


@router.post("/stream")
async def stream_message(
    request: Request,
    chat_request: ChatRequest,
    ai_service: AIService = Depends(get_ai_service),
):
    """
    流式聊天消息

    Args:
        request: HTTP请求对象
        chat_request: 聊天请求
        ai_service: AI服务实例

    Returns:
        StreamingResponse: 流式响应
    """
    try:
        logger.info(f"收到流式聊天请求，消息数量: {len(chat_request.messages)}")

        # 尝试获取考试ID并加载考试上下文
        user_exam_id = request.query_params.get("examId")

        if user_exam_id:
            logger.info(f"流式聊天尝试加载考试上下文: {user_exam_id}")
            exam_context = await load_exam_context(user_exam_id, dict(request.headers))
            if exam_context:
                logger.info("流式聊天成功加载考试上下文")
                # 将考试上下文合并到请求中
                chat_request.exam_context = exam_context
            else:
                logger.warning("流式聊天加载考试上下文失败，使用默认上下文")

        # 验证消息格式
        if not chat_request.messages:
            raise HTTPException(status_code=400, detail="消息列表不能为空")

        async def generate_response():
            try:
                async for chunk in ai_service.chat_stream(chat_request):
                    # 以SSE格式发送数据
                    yield f"data: {json.dumps({'content': chunk}, ensure_ascii=False)}\n\n"

                # 发送结束信号
                yield f"data: {json.dumps({'done': True}, ensure_ascii=False)}\n\n"

            except Exception as e:
                logger.error(f"流式聊天错误: {e}")
                yield f"data: {json.dumps({'error': str(e)}, ensure_ascii=False)}\n\n"

        return StreamingResponse(
            generate_response(),
            media_type="text/plain",
            headers={
                "Cache-Control": "no-cache",
                "Connection": "keep-alive",
                "Content-Type": "text/plain; charset=utf-8",
            },
        )

    except Exception as e:
        logger.error(f"流式聊天服务错误: {e}")
        raise HTTPException(status_code=500, detail=f"流式聊天服务错误: {str(e)}")


@router.get("/health")
async def health_check():
    """健康检查"""
    return {"status": "ok", "service": "chat_api"}


@router.post("/analyze-exam")
async def analyze_exam_result(
    exam_data: Dict, ai_service: AIService = Depends(get_ai_service)
) -> ChatResponse:
    """
    分析考试结果并生成建议

    Args:
        exam_data: 考试数据
        ai_service: AI服务实例

    Returns:
        ChatResponse: 分析结果和建议
    """
    try:
        logger.info(f"收到考试分析请求，考试ID: {exam_data.get('exam_id', 'unknown')}")

        # 使用Jinja模板构建分析请求
        analysis_prompt = render_prompt("exam_analysis.jinja", exam_data=exam_data)

        # 创建聊天请求
        request = ChatRequest(
            messages=[ChatMessage(role="user", content=analysis_prompt)],
            exam_context=exam_data,
            user_exam_id=exam_data.get("exam_id", ""),
        )

        # 调用AI服务
        response = await ai_service.chat(request)

        logger.info("考试分析完成")
        return response

    except Exception as e:
        logger.error(f"考试分析错误: {e}")
        raise HTTPException(status_code=500, detail=f"考试分析错误: {str(e)}")
